﻿using Microsoft.SharePoint.Administration;
using SPDocumentor.SPModel.SPServiceApplications;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace SPDocumentor.SPHelpers
{
    public static class ServiceApplicationFactory
    {
        public static ServiceApplication GetServiceApplication(SPServiceApplication spsa)
        {
            ServiceApplication sa;

            IEnumerable<Object> iobjs;
            List<ServiceApplicationDB> lstDB;
            Type tsa = spsa.GetType();
            switch (tsa.Name)
            {
                case "AppManagementServiceApplication":
                    {
                        sa = new AppManagementSA();
                        iobjs = (IEnumerable<Object>)tsa.GetProperty("Databases").GetValue(spsa);
                        lstDB = new List<ServiceApplicationDB>();
                        foreach (object obj in iobjs)
                        {
                            ServiceApplicationDB db = new ServiceApplicationDB();

                            Type tdb = obj.GetType();
                            db.DatabaseConnectionString = tdb.GetProperty("DatabaseConnectionString").GetValue(obj).ToString();
                            db.DiskSizeRequired = int.Parse(tdb.GetProperty("DiskSizeRequired").GetValue(obj).ToString());
                            db.LegacyDatabaseConnectionString = tdb.GetProperty("LegacyDatabaseConnectionString").GetValue(obj).ToString();
                            lstDB.Add(db);
                        }
                        ((AppManagementSA)sa).Databases = lstDB.ToArray();
                    }
                    break;
                case "MetadataWebServiceApplication":
                    sa = new MetadataWebSA();
                    if (tsa.GetProperty("Database") == null)
                        break;
                    object objo = tsa.GetProperty("Database").GetValue(spsa);
                    lstDB = new List<ServiceApplicationDB>();
                    ServiceApplicationDB dbo = new ServiceApplicationDB();
                    Type tdbo = objo.GetType();
                    dbo.DatabaseConnectionString = tdbo.GetProperty("DatabaseConnectionString").GetValue(objo).ToString();
                    dbo.DiskSizeRequired = int.Parse(tdbo.GetProperty("DiskSizeRequired").GetValue(objo).ToString());
                    dbo.LegacyDatabaseConnectionString = tdbo.GetProperty("LegacyDatabaseConnectionString").GetValue(objo).ToString();
                    lstDB.Add(dbo);
                    ((MetadataWebSA)sa).Databases = lstDB.ToArray();
                    break;
                case "SPUsageApplication":
                    sa = new SPUsageSA();
                    if (tsa.GetProperty("UsageDatabase") == null)
                        break;
                    object objUsage = tsa.GetProperty("UsageDatabase").GetValue(spsa);
                    lstDB = new List<ServiceApplicationDB>();
                    ServiceApplicationDB dbusage = new ServiceApplicationDB();
                    Type tdbUsage = objUsage.GetType();
                    dbusage.DatabaseConnectionString = tdbUsage.GetProperty("DatabaseConnectionString").GetValue(objUsage).ToString();
                    dbusage.DiskSizeRequired = long.Parse(tdbUsage.GetProperty("DiskSizeRequired").GetValue(objUsage).ToString());
                    dbusage.LegacyDatabaseConnectionString = tdbUsage.GetProperty("LegacyDatabaseConnectionString").GetValue(objUsage).ToString();
                    lstDB.Add(dbusage);
                    ((SPUsageSA)sa).Databases = lstDB.ToArray();
                    ((SPUsageSA)sa).LoggingEnabled = Convert.ToBoolean(tsa.GetProperty("LoggingEnabled").GetValue(spsa));
                    ((SPUsageSA)sa).UsageInsertionTimeOut = Convert.ToInt32(tsa.GetProperty("UsageInsertionTimeOut").GetValue(spsa));
                    break;
                case "SearchAdminWebServiceApplication":
                    sa = new SearchAdminWebSA();
                    break;
                case "SecureStoreServiceApplication":
                    sa = new SecureStoreSA();
                    break;
                case "BIMonitoringServiceApplication":
                    sa = new BIMonitoringSA();
                    ServiceApplicationDB dbBIMonitoring = new ServiceApplicationDB();
                    if (tsa.GetProperty("Database") == null)
                        break;
                    object obBIMonitoring = tsa.GetProperty("Database").GetValue(spsa);
                    Type tdbBIMonitoring = obBIMonitoring.GetType();
                    dbBIMonitoring.DatabaseConnectionString = tdbBIMonitoring.GetProperty("DatabaseConnectionString").GetValue(obBIMonitoring).ToString();
                    dbBIMonitoring.DiskSizeRequired = int.Parse(tdbBIMonitoring.GetProperty("DiskSizeRequired").GetValue(obBIMonitoring).ToString());
                    dbBIMonitoring.LegacyDatabaseConnectionString = tdbBIMonitoring.GetProperty("LegacyDatabaseConnectionString").GetValue(obBIMonitoring).ToString();
                    ((BIMonitoringSA)sa).Database = dbBIMonitoring;
                    break;

                case "ReportingWebServiceApplication":
                    sa = new ReportingWebSA();
                    ServiceApplicationDB dbReporting = new ServiceApplicationDB();
                    if (tsa.GetProperty("CatalogDatabase") == null)
                        break;
                    object obReporting = tsa.GetProperty("CatalogDatabase").GetValue(spsa);
                    Type tdbReporting = obReporting.GetType();
                    dbReporting.DatabaseConnectionString = tdbReporting.GetProperty("DatabaseConnectionString").GetValue(obReporting).ToString();
                    dbReporting.DiskSizeRequired = int.Parse(tdbReporting.GetProperty("DiskSizeRequired").GetValue(obReporting).ToString());
                    dbReporting.LegacyDatabaseConnectionString = tdbReporting.GetProperty("LegacyDatabaseConnectionString").GetValue(obReporting).ToString();
                    ((ReportingWebSA)sa).Database = dbReporting;
                    ((ReportingWebSA)sa).DatabaseLogonType = tsa.GetProperty("DatabaseLogonType").GetValue(spsa).ToString();
                    ((ReportingWebSA)sa).DatabaseLogonWindowsAccount = tsa.GetProperty("DatabaseLogonWindowsAccount").GetValue(spsa) == null ? "" : tsa.GetProperty("DatabaseLogonWindowsAccount").GetValue(spsa).ToString();
                    ((ReportingWebSA)sa).UEAccountName = tsa.GetProperty("UEAccountName").GetValue(spsa) == null ? "" : tsa.GetProperty("UEAccountName").GetValue(spsa).ToString();
                    break;
                case "VisioGraphicsServiceApplication":
                    sa = new VisioGraphicsSA();
                    break;
                case "GeminiServiceApplication":
                    sa = new GeminiSA();
                    ((GeminiSA)sa).AllocationTimeout = Convert.ToInt32(tsa.GetProperty("AllocationTimeout").GetValue(spsa));
                    ((GeminiSA)sa).AllowCustomWindowsCredentialForDataRefresh = Convert.ToBoolean(tsa.GetProperty("AllowCustomWindowsCredentialsForDataRefresh").GetValue(spsa));
                    ((GeminiSA)sa).CacheCleanerInterval = Convert.ToInt32(tsa.GetProperty("CacheCleanerInterval").GetValue(spsa));
                    ((GeminiSA)sa).CheckCachedDbInterval = Convert.ToInt32(tsa.GetProperty("CheckCachedDbInterval").GetValue(spsa));
                    ((GeminiSA)sa).CheckInstanceMapInterval = Convert.ToInt32(tsa.GetProperty("CheckInstanceMapInterval").GetValue(spsa));
                    ((GeminiSA)sa).CheckLastestDbInterval = Convert.ToInt32(tsa.GetProperty("CheckLastestDbInterval") == null ? 0 : tsa.GetProperty("CheckLastestDbInterval").GetValue(spsa));
                    ((GeminiSA)sa).CheckRuningDbInterval = Convert.ToInt32(tsa.GetProperty("CheckRuningDbInterval") == null ? 0 : tsa.GetProperty("CheckRuningDbInterval").GetValue(spsa));
                    ((GeminiSA)sa).ConnectionString = tsa.GetProperty("ConnectionString").GetValue(spsa).ToString();
                    ((GeminiSA)sa).ConnectionTimeout = Convert.ToInt32(tsa.GetProperty("ConnectionTimeout").GetValue(spsa));
                    ((GeminiSA)sa).CubeFileName = tsa.GetProperty("CubeFileName").GetValue(spsa).ToString();
                    ((GeminiSA)sa).DashboardRefreshAccount = tsa.GetProperty("DashboardRefreshAccount").GetValue(spsa).ToString();
                    ServiceApplicationDB dbGemini = new ServiceApplicationDB();
                    object obGemini = tsa.GetProperty("Database").GetValue(spsa);
                    Type tdbGemini = obGemini.GetType();
                    dbGemini.DatabaseConnectionString = tdbGemini.GetProperty("DatabaseConnectionString").GetValue(obGemini).ToString();
                    dbGemini.DiskSizeRequired = int.Parse(tdbGemini.GetProperty("DiskSizeRequired").GetValue(obGemini).ToString());
                    dbGemini.LegacyDatabaseConnectionString = tdbGemini.GetProperty("LegacyDatabaseConnectionString").GetValue(obGemini).ToString();
                    ((GeminiSA)sa).Database = dbGemini;
                    ((GeminiSA)sa).DataRefreshMaxHistory = Convert.ToInt32(tsa.GetProperty("DataRefreshMaxHistory").GetValue(spsa));
                    ((GeminiSA)sa).DelayRefreshOnNoServerAvaible = Convert.ToInt32(tsa.GetProperty("DelayRefreshOnNoServersAvailable").GetValue(spsa));
                    ((GeminiSA)sa).DisableAfterFailures = Convert.ToInt32(tsa.GetProperty("DisableAfterFailures").GetValue(spsa));
                    ((GeminiSA)sa).DisableAfterInactivity = Convert.ToInt32(tsa.GetProperty("DisableAfterInactivity").GetValue(spsa));
                    ((GeminiSA)sa).HealthCalculationInterval = Convert.ToInt32(tsa.GetProperty("HealthCalculationInterval").GetValue(spsa));
                    ((GeminiSA)sa).Lcid = Convert.ToUInt32(tsa.GetProperty("Lcid").GetValue(spsa));
                    ((GeminiSA)sa).LoadsToConnectionsRatioHourRange = Convert.ToInt32(tsa.GetProperty("LoadsToConnectionsRatioHourRange").GetValue(spsa));
                    ((GeminiSA)sa).LoadsToConnectionsRatioLimit = Convert.ToInt32(tsa.GetProperty("LoadsToConnectionsRatioLimit").GetValue(spsa));
                    ((GeminiSA)sa).LoadTimeout = Convert.ToInt32(tsa.GetProperty("LoadTimeout").GetValue(spsa));
                    ((GeminiSA)sa).MaxAdminConnectionPoolSize = Convert.ToInt32(tsa.GetProperty("MaxAdminConnectionPoolSize").GetValue(spsa));
                    ((GeminiSA)sa).MaxUserConnectionPoolSize = Convert.ToInt32(tsa.GetProperty("MaxUserConnectionPoolSize").GetValue(spsa));
                    ((GeminiSA)sa).NumberOfParallelRefreshJobs = Convert.ToInt32(tsa.GetProperty("NumberOfParallelRefreshJobs").GetValue(spsa));
                    ((GeminiSA)sa).OldestCachedDbLimit = Convert.ToInt32(tsa.GetProperty("OldestCachedDbLimit").GetValue(spsa));
                    ((GeminiSA)sa).OldestRunningDbLimit = Convert.ToInt32(tsa.GetProperty("OldestRunningDbLimit").GetValue(spsa));
                    ((GeminiSA)sa).RescheduleBasedOnTodayOnNoAvailableServers = Convert.ToBoolean(tsa.GetProperty("RescheduleBasedOnTodayOnNoAvailableServers").GetValue(spsa));
                    ((GeminiSA)sa).ServiceAppFolderUrl = tsa.GetProperty("ServiceAppFolderUrl").GetValue(spsa).ToString();
                    ((GeminiSA)sa).StartMigratingRefreshSchedules = Convert.ToBoolean(tsa.GetProperty("StartMigratingRefreshSchedules").GetValue(spsa));
                    ((GeminiSA)sa).UnattendedAccount = tsa.GetProperty("UnattendedAccount").GetValue(spsa).ToString();
                    ((GeminiSA)sa).UsageAndHealthRetentionPeriod = Convert.ToInt32(tsa.GetProperty("UsageAndHealthRetentionPeriod").GetValue(spsa));
                    ((GeminiSA)sa).UsageExpectedUpperLimit = Convert.ToInt32(tsa.GetProperty("UsageExpectedUpperLimit").GetValue(spsa));
                    ((GeminiSA)sa).UsageLongUpperLimit = Convert.ToInt32(tsa.GetProperty("UsageLongUpperLimit").GetValue(spsa));
                    ((GeminiSA)sa).UsageQuickUpperLimit = Convert.ToInt32(tsa.GetProperty("UsageQuickUpperLimit").GetValue(spsa));
                    ((GeminiSA)sa).UsageRequestsTimeToReport = Convert.ToInt32(tsa.GetProperty("UsageRequestsTimeToReport").GetValue(spsa));
                    ((GeminiSA)sa).UsageTrivialUpperLimit = Convert.ToInt32(tsa.GetProperty("UsageTrivialUpperLimit").GetValue(spsa));
                    ((GeminiSA)sa).UsageUpdateDayLimit = Convert.ToInt32(tsa.GetProperty("UsageUpdateDayLimit").GetValue(spsa));
                    ((GeminiSA)sa).UsageWorkbookLastSuccessfulUpdate = Convert.ToDateTime(tsa.GetProperty("UsageWorkbookLastSuccessfulUpdate").GetValue(spsa));
                    ((GeminiSA)sa).UsageWorkbookLastUpdateAttempt = Convert.ToDateTime(tsa.GetProperty("UsageWorkbookLastUpdateAttempt").GetValue(spsa));
                    ((GeminiSA)sa).UsageWorkbookLastUpdateErrorMessage = tsa.GetProperty("UsageWorkbookLastUpdateErrorMessage").GetValue(spsa) == null ? "" : tsa.GetProperty("UsageWorkbookLastUpdateErrorMessage").GetValue(spsa).ToString();
                    break;
                case "SearchServiceApplication":
                    sa = new SearchSA();
                    object at = tsa.GetProperty("ActiveTopology").GetValue(spsa);
                    Topology actTopology = new Topology();
                    actTopology.ComponentCount = Convert.ToInt32(at.GetType().GetProperty("ComponentCount").GetValue(at));
                    actTopology.CreationDate = Convert.ToDateTime(at.GetType().GetProperty("CreationDate").GetValue(at));
                    actTopology.State = at.GetType().GetProperty("State").GetValue(at).ToString();
                    actTopology.TopologyId = Guid.Parse(at.GetType().GetProperty("TopologyId").GetValue(at).ToString());
                    ((SearchSA)sa).ActiveTopology = actTopology;
                    SearchComponent admComponent = new SearchComponent();
                    object ac = tsa.GetProperty("AdminComponent").GetValue(spsa);
                    admComponent.IndexLocation = ac.GetType().GetProperty("IndexLocation").GetValue(ac).ToString();
                    admComponent.Initialized = Convert.ToBoolean(ac.GetType().GetProperty("Initialized").GetValue(ac));
                    admComponent.Server = ac.GetType().GetProperty("ServerName").GetValue(ac).ToString();
                    ((SearchSA)sa).AdminComponent = admComponent;
                    ((SearchSA)sa).AlertNotificationFormat = tsa.GetProperty("AlertNotificationFormat").GetValue(spsa) == null ? "" : tsa.GetProperty("AlertNotificationFormat").ToString();
                    ((SearchSA)sa).AlertNotificationQuota = Convert.ToInt32(tsa.GetProperty("AlertNotificationQuota").GetValue(spsa));
                    ((SearchSA)sa).AlertsEnabled = Convert.ToBoolean(tsa.GetProperty("AlertsEnabled").GetValue(spsa));
                    ((SearchSA)sa).AllowedMaxRowLimitSp14 = Convert.ToInt32(tsa.GetProperty("AllowedMaxRowLimitSp14").GetValue(spsa));
                    ((SearchSA)sa).AllowPartialResults = Convert.ToBoolean(tsa.GetProperty("AllowPartialResults").GetValue(spsa));
                    ((SearchSA)sa).AllowQueryDebugMode = Convert.ToBoolean(tsa.GetProperty("AllowQueryDebugMode").GetValue(spsa));

                    IEnumerable<object> lstObj = (IEnumerable<object>)tsa.GetProperty("AnalyticsReportingDatabases").GetValue(spsa);
                    List<ServiceApplicationDB> lstARD = new List<ServiceApplicationDB>();
                    foreach (object o in lstObj)
                    {
                        ServiceApplicationDB sadb = new ServiceApplicationDB();
                        sadb.DatabaseConnectionString = o.GetType().GetProperty("DatabaseConnectionString").GetValue(o).ToString();
                        sadb.DiskSizeRequired = Convert.ToInt32(o.GetType().GetProperty("DiskSizeRequired").GetValue(o));
                        sadb.LegacyDatabaseConnectionString = o.GetType().GetProperty("LegacyDatabaseConnectionString").GetValue(o).ToString();
                        lstARD.Add(sadb);
                    }
                    ((SearchSA)sa).AnalyticsReportingDatabases = lstARD.ToArray();


                    lstObj = (IEnumerable<object>)tsa.GetProperty("AnalyticsReportingStores").GetValue(spsa);
                    lstARD = new List<ServiceApplicationDB>();
                    foreach (object o in lstObj)
                    {
                        ServiceApplicationDB sadb = new ServiceApplicationDB();
                        object oDB = o.GetType().GetProperty("Database").GetValue(o);
                        sadb.DatabaseConnectionString = oDB.GetType().GetProperty("DatabaseConnectionString").GetValue(oDB).ToString();
                        sadb.DiskSizeRequired = Convert.ToInt32(oDB.GetType().GetProperty("DiskSizeRequired").GetValue(oDB));
                        sadb.LegacyDatabaseConnectionString = oDB.GetType().GetProperty("LegacyDatabaseConnectionString").GetValue(oDB).ToString();
                        lstARD.Add(sadb);
                    }

                    ((SearchSA)sa).AnalyticsReportingStores = lstARD.ToArray();

                    ((SearchSA)sa).ApplicationName = tsa.GetProperty("ApplicationName").GetValue(spsa).ToString();
                    ((SearchSA)sa).CpuBasedQueryThrottling = Convert.ToBoolean(tsa.GetProperty("CpuBasedQueryThrottling").GetValue(spsa));

                    List<SearchComponent> crlComponents = new List<SearchComponent>();
                    IEnumerable<object> cc = (IEnumerable<object>)tsa.GetProperty("CrawlComponents").GetValue(spsa);
                    foreach (object c in cc)
                    {
                        SearchComponent crlComponent = new SearchComponent();
                        crlComponent.IndexLocation = c.GetType().GetProperty("IndexLocation").GetValue(c).ToString();
                        crlComponent.State = c.GetType().GetProperty("State").GetValue(c).ToString();
                        crlComponent.Server = c.GetType().GetProperty("ServerName").GetValue(c).ToString();
                        crlComponents.Add(crlComponent);
                    }
                    ((SearchSA)sa).CrawlComponents = crlComponents.ToArray();
                    ((SearchSA)sa).CrawlLogCleanupIntervalInDays = Convert.ToInt32(tsa.GetProperty("CrawlLogCleanupIntervalInDays").GetValue(spsa));

                    lstObj = (IEnumerable<object>)tsa.GetProperty("CrawlStores").GetValue(spsa);
                    lstARD = new List<ServiceApplicationDB>();
                    foreach (object o in lstObj)
                    {
                        ServiceApplicationDB sadb = new ServiceApplicationDB();
                        object oDB = o.GetType().GetProperty("Database").GetValue(o);
                        sadb.DatabaseConnectionString = oDB.GetType().GetProperty("DatabaseConnectionString").GetValue(oDB).ToString();
                        sadb.DiskSizeRequired = Convert.ToInt32(oDB.GetType().GetProperty("DiskSizeRequired").GetValue(oDB));
                        sadb.LegacyDatabaseConnectionString = oDB.GetType().GetProperty("LegacyDatabaseConnectionString").GetValue(oDB).ToString();
                        lstARD.Add(sadb);
                    }

                    ((SearchSA)sa).CrawlStores = lstARD.ToArray();
                    ((SearchSA)sa).DefaultQueryTimeout = Convert.ToInt32(tsa.GetProperty("DefaultQueryTimeout").GetValue(spsa));
                    ((SearchSA)sa).DefaultSearchProvider = tsa.GetProperty("DefaultSearchProvider").GetValue(spsa).ToString();
                    ((SearchSA)sa).DiacriticSensitive = Convert.ToBoolean(tsa.GetProperty("DiacriticSensitive").GetValue(spsa));
                    ((SearchSA)sa).DiscoveryMaxKeywordQueryTextLength = Convert.ToInt32(tsa.GetProperty("DiscoveryMaxKeywordQueryTextLength").GetValue(spsa));
                    ((SearchSA)sa).DiscoveryMaxRowLimit = Convert.ToInt32(tsa.GetProperty("DiscoveryMaxRowLimit").GetValue(spsa));
                    ((SearchSA)sa).EnableIMS = Convert.ToBoolean(tsa.GetProperty("EnableIMS").GetValue(spsa));
                    ((SearchSA)sa).FarmIdsForAlerts = (List<Guid>)(tsa.GetProperty("FarmIdsForAlerts").GetValue(spsa));
                    //((SearchSA)sa).FASTAdminProxy = tsa.GetProperty("FASTAdminProxy").GetValue(spsa) == null ? "" : tsa.GetProperty("FASTAdminProxy").GetValue(spsa).ToString();
                    ((SearchSA)sa).HeadQueryFrequencyThreshold = Convert.ToInt32(tsa.GetProperty("HeadQueryFrequencyThreshold").GetValue(spsa));
                    ((SearchSA)sa).LatencyBasedQueryThrottling = Convert.ToBoolean(tsa.GetProperty("LatencyBasedQueryThrottling").GetValue(spsa));

                    lstObj = (IEnumerable<object>)tsa.GetProperty("LinksStores").GetValue(spsa);
                    lstARD = new List<ServiceApplicationDB>();
                    foreach (object o in lstObj)
                    {
                        ServiceApplicationDB sadb = new ServiceApplicationDB();
                        object oDB = o.GetType().GetProperty("Database").GetValue(o);
                        sadb.DatabaseConnectionString = oDB.GetType().GetProperty("DatabaseConnectionString").GetValue(oDB).ToString();
                        sadb.DiskSizeRequired = Convert.ToInt32(oDB.GetType().GetProperty("DiskSizeRequired").GetValue(oDB));
                        sadb.LegacyDatabaseConnectionString = oDB.GetType().GetProperty("LegacyDatabaseConnectionString").GetValue(oDB).ToString();
                        lstARD.Add(sadb);
                    }
                    ((SearchSA)sa).LinksStores = lstARD.ToArray();
                    ((SearchSA)sa).LoadBasedQueryThrottling = Convert.ToBoolean(tsa.GetProperty("LoadBasedQueryThrottling").GetValue(spsa));
                    IEnumerable<object> oLocationConfs = (IEnumerable<object>)tsa.GetProperty("LocationConfigurations").GetValue(spsa);
                    List<LocationConfiguration> lstLC = new List<LocationConfiguration>();
                    object oTemp;
                    foreach (object o in oLocationConfs)
                    {
                        LocationConfiguration lc = new LocationConfiguration();

                        lc.AdminDescription = o.GetType().GetProperty("AdminDescription").GetValue(o).ToString();
                        oTemp = o.GetType().GetProperty("AllowedSiteCollectionGuids").GetValue(o);
                        if (oTemp != null)
                            lc.AllowedSiteCollectionGuids = new List<Guid>((IList<System.Guid>)oTemp);
                        lc.AllowedSiteCollectionUrls = (StringCollection)o.GetType().GetProperty("AllowedSiteCollectionUrls").GetValue(o);
                        lc.Author = o.GetType().GetProperty("Author").GetValue(o) == null ? "" : o.GetType().GetProperty("Author").GetValue(o).ToString();
                        lc.ConnectionUrlTemplate = o.GetType().GetProperty("ConnectionUrlTemplate").GetValue(o).ToString();
                        lc.CreationDate = Convert.ToDateTime(o.GetType().GetProperty("CreationDate").GetValue(o));
                        lc.DescriptionXml = o.GetType().GetProperty("DescriptionXml").GetValue(o) == null ? "" : o.GetType().GetProperty("DescriptionXml").GetValue(o).ToString();
                        lc.InternalName = o.GetType().GetProperty("InternalName").GetValue(o).ToString();
                        lc.IsDeletable = Convert.ToBoolean(o.GetType().GetProperty("IsDeletable").GetValue(o));
                        lc.IsPrefixPattern = Convert.ToBoolean(o.GetType().GetProperty("IsPrefixPattern").GetValue(o));
                        lc.IsRestrictedLocation = Convert.ToBoolean(o.GetType().GetProperty("IsRestrictedLocation").GetValue(o));
                        lc.KindsOfResults = o.GetType().GetProperty("KindsOfResults").GetValue(o) == null ? "" : o.GetType().GetProperty("KindsOfResults").GetValue(o).ToString();
                        oTemp = o.GetType().GetProperty("Languages").GetValue(o);
                        if (oTemp != null)
                        {
                            List<System.Globalization.CultureInfo> lstCI = new List<System.Globalization.CultureInfo>((IList<System.Globalization.CultureInfo>)oTemp);
                            List<string> lstStrCI = new List<string>();
                            foreach (System.Globalization.CultureInfo ci in lstCI)
                            {
                                lstStrCI.Add(ci.Name);
                            }
                            lc.Languages = lstStrCI;
                        }
                        lc.LastModifiedDate = Convert.ToDateTime(o.GetType().GetProperty("LastModifiedDate").GetValue(o));
                        lc.MoreLinkTemplate = o.GetType().GetProperty("MoreLinkTemplate").GetValue(o).ToString();
                        lc.Name = o.GetType().GetProperty("Name").GetValue(o).ToString();
                        lc.ProxyUrl = o.GetType().GetProperty("ProxyUrl").GetValue(o) == null ? "" : o.GetType().GetProperty("ProxyUrl").GetValue(o).ToString();
                        lc.QueryReformatPattern = o.GetType().GetProperty("QueryReformatPattern").GetValue(o) == null ? "" : o.GetType().GetProperty("QueryReformatPattern").GetValue(o).ToString();
                        lc.QueryRestriction = o.GetType().GetProperty("QueryRestriction").GetValue(o) == null ? "" : o.GetType().GetProperty("QueryRestriction").GetValue(o).ToString();
                        lc.Type = o.GetType().GetProperty("Type").GetValue(o).ToString();

                        lstLC.Add(lc);
                    }

                    ((SearchSA)sa).LocationConfigurations = lstLC.ToArray();
                    ((SearchSA)sa).MaxKeywordQueryTextLength = Convert.ToInt32(tsa.GetProperty("MaxKeywordQueryTextLength").GetValue(spsa));
                    ((SearchSA)sa).MaxQueryTimeout = Convert.ToInt32(tsa.GetProperty("MaxQueryTimeout").GetValue(spsa));
                    ((SearchSA)sa).MaxRankingModels = Convert.ToInt32(tsa.GetProperty("MaxRankingModels").GetValue(spsa));
                    ((SearchSA)sa).MaxRowLimit = Convert.ToInt32(tsa.GetProperty("MaxRowLimit").GetValue(spsa));
                    ((SearchSA)sa).MinimumReadyQueryComponentsPerPartition = Convert.ToInt32(tsa.GetProperty("MinimumReadyQueryComponentsPerPartition").GetValue(spsa));
                    ((SearchSA)sa).NameNormalizationEnabled = Convert.ToBoolean(tsa.GetProperty("NameNormalizationEnabled").GetValue(spsa));
                    ((SearchSA)sa).NameNormalizationPreferredNamePID = Convert.ToInt32(tsa.GetProperty("NameNormalizationPreferredNamePID").GetValue(spsa));
                    ((SearchSA)sa).PersonalQuerySuggestionsEnabled = Convert.ToBoolean(tsa.GetProperty("PersonalQuerySuggestionsEnabled").GetValue(spsa));
                    ((SearchSA)sa).QueryLoggingEnabled = Convert.ToBoolean(tsa.GetProperty("QueryLoggingEnabled").GetValue(spsa));
                    //((SearchSA)sa).QueryLogSettings = tsa.GetProperty("QueryLogSettings").GetValue(spsa).ToString();
                    ((SearchSA)sa).QuerySuggestionsEnabled = Convert.ToBoolean(tsa.GetProperty("QuerySuggestionsEnabled").GetValue(spsa));
                    ((SearchSA)sa).ResetAndEnableAlerts = Convert.ToBoolean(tsa.GetProperty("ResetAndEnableAlerts").GetValue(spsa));
                    object osearchadmindb = tsa.GetProperty("SearchAdminDatabase").GetValue(spsa);
                    ServiceApplicationDB searchadmindb = new ServiceApplicationDB();
                    searchadmindb.DatabaseConnectionString = osearchadmindb.GetType().GetProperty("DatabaseConnectionString").GetValue(osearchadmindb).ToString();
                    searchadmindb.DiskSizeRequired = Convert.ToInt32(osearchadmindb.GetType().GetProperty("DiskSizeRequired").GetValue(osearchadmindb));
                    searchadmindb.LegacyDatabaseConnectionString = osearchadmindb.GetType().GetProperty("LegacyDatabaseConnectionString").GetValue(osearchadmindb).ToString();
                    ((SearchSA)sa).SearchAdminDatabase = searchadmindb;
                    ((SearchSA)sa).SearchCenterUrl = tsa.GetProperty("SearchCenterUrl").GetValue(spsa).ToString();
                    ((SearchSA)sa).SharedSearchBoxSettings = tsa.GetProperty("SharedSearchBoxSettings").GetValue(spsa) == null ? "" : tsa.GetProperty("SharedSearchBoxSettings").GetValue(spsa).ToString();
                    List<string> lstStr = new List<string>();
                    IEnumerable<Uri> enumUri = (IEnumerable<Uri>)tsa.GetProperty("SystemManagerLocations").GetValue(spsa);
                    foreach (Uri uri in enumUri)
                    {
                        lstStr.Add(uri.AbsoluteUri);
                    }
                    ((SearchSA)sa).SystemManagerLocations = lstStr.ToArray();
                    ((SearchSA)sa).TimeBeforeAbandoningQueryComponent = tsa.GetProperty("TimeBeforeAbandoningQueryComponent").GetValue(spsa).ToString();
                    //((SearchSA)sa).Topologies = tsa.GetProperty("Topologies").GetValue(spsa).ToString();
                    //((SearchSA)sa).UrlZoneOverride = tsa.GetProperty("UrlZoneOverride").GetValue(spsa).ToString();
                    ((SearchSA)sa).UseSimpleSchemaUI = Convert.ToBoolean(tsa.GetProperty("UseSimpleSchemaUI").GetValue(spsa));
                    ((SearchSA)sa).VerboseQueryMonitoring = Convert.ToBoolean(tsa.GetProperty("VerboseQueryMonitoring").GetValue(spsa));
                    ((SearchSA)sa).VerboseSubFlowTiming = Convert.ToBoolean(tsa.GetProperty("VerboseSubFlowTiming").GetValue(spsa));
                    break;
                case "WorkManagementServiceApplication":
                    sa = new WorkManagementSA();
                    WorkManagementAdminSettings wmas = new WorkManagementAdminSettings();
                    object owmas = tsa.GetProperty("AdminSettings").GetValue(spsa);
                    wmas.MinimumTimeBetweenEwsSyncSubscriptionSearches = (TimeSpan)owmas.GetType().GetProperty("MinimumTimeBetweenEwsSyncSubscriptionSearches").GetValue(owmas);
                    wmas.MinimumTimeBetweenProviderRefreshes = (TimeSpan)owmas.GetType().GetProperty("MinimumTimeBetweenProviderRefreshes").GetValue(owmas);
                    wmas.MinimumTimeBetweenSearchQueries = (TimeSpan)owmas.GetType().GetProperty("MinimumTimeBetweenSearchQueries").GetValue(owmas);
                    wmas.NumberOfSubscriptionSyncsPerEwsSyncRun = Convert.ToUInt32(owmas.GetType().GetProperty("NumberOfSubscriptionSyncsPerEwsSyncRun").GetValue(owmas));
                    wmas.NumberOfUsersEwsSyncWillProcessAtOnce = Convert.ToUInt32(owmas.GetType().GetProperty("NumberOfUsersEwsSyncWillProcessAtOnce").GetValue(owmas));
                    wmas.NumberOfUsersPerEwsSyncBatch = Convert.ToUInt32(owmas.GetType().GetProperty("NumberOfUsersPerEwsSyncBatch").GetValue(owmas));
                    ((WorkManagementSA)sa).AdminSettings = wmas;
                    ((WorkManagementSA)sa).WmaService = tsa.GetProperty("WmaService").GetValue(spsa).ToString();
                    break;
                case "SPSecurityTokenServiceApplication":
                    sa = new SPSecurityTokenSA();
                    System.Security.Cryptography.X509Certificates.X509Certificate2 Cert = (System.Security.Cryptography.X509Certificates.X509Certificate2)tsa.GetProperty("EncryptionCertificate").GetValue(spsa);
                    ((SPSecurityTokenSA)sa).EncryptionCertificate = Cert.FriendlyName + " Issuer: " + Cert.IssuerName.Name + " Subject:" + Cert.SubjectName.Name;
                    ((SPSecurityTokenSA)sa).EncryptionCertificateStoreName = tsa.GetProperty("EncryptionCertificateStoreName").GetValue(spsa).ToString();
                    ((SPSecurityTokenSA)sa).EncryptionCertificateThumbprint = tsa.GetProperty("EncryptionCertificateThumbprint").GetValue(spsa).ToString();
                    Cert = (System.Security.Cryptography.X509Certificates.X509Certificate2)tsa.GetProperty("NextSignginCertificate").GetValue(spsa);
                    if (Cert != null)
                        ((SPSecurityTokenSA)sa).NextSignginCertificate = Cert.FriendlyName == null ? "" : Cert.FriendlyName + " Issuer: " + Cert.IssuerName == null ? "" : Cert.IssuerName.Name + " Subject:" + Cert.SubjectName == null ? "" : Cert.SubjectName.Name;
                    ((SPSecurityTokenSA)sa).NextSigningCertificateStoreName = tsa.GetProperty("NextSigningCertificateStoreName").GetValue(spsa).ToString();
                    ((SPSecurityTokenSA)sa).NextSigningCertificateThumbprint = tsa.GetProperty("NextSigningCertificateThumbprint").GetValue(spsa) == null ? "" : tsa.GetProperty("NextSigningCertificateThumbprint").GetValue(spsa).ToString();
                    Cert = (System.Security.Cryptography.X509Certificates.X509Certificate2)tsa.GetProperty("SigningCertificate").GetValue(spsa);
                    ((SPSecurityTokenSA)sa).SigningCertificate = Cert.FriendlyName + " Issuer: " + Cert.IssuerName.Name + " Subject:" + Cert.SubjectName.Name;
                    ((SPSecurityTokenSA)sa).SigningCertificateStoreName = tsa.GetProperty("SigningCertificateStoreName").GetValue(spsa).ToString();
                    ((SPSecurityTokenSA)sa).SigningCertificateThumbprint = tsa.GetProperty("SigningCertificateThumbprint").GetValue(spsa).ToString();
                    break;
                case "ExcelServerWebServiceApplication":
                    sa = new ExcelServerWebSA();
                    ((ExcelServerWebSA)sa).CachingOfUnusedFilesEnable = tsa.GetProperty("CachingOfUnusedFilesEnable").GetValue(spsa).ToString();
                    ((ExcelServerWebSA)sa).CrossDomainAccessAllowed = tsa.GetProperty("CrossDomainAccessAllowed").GetValue(spsa).ToString();
                    ((ExcelServerWebSA)sa).EncryptedUserConnectionRequired = tsa.GetProperty("EncryptedUserConnectionRequired").GetValue(spsa).ToString();
                    ((ExcelServerWebSA)sa).ExternalDataConnectionLifetime = tsa.GetProperty("ExternalDataConnectionLifetime").GetValue(spsa).ToString();
                    ((ExcelServerWebSA)sa).FileAccessMethod = tsa.GetProperty("FileAccessMethod").GetValue(spsa).ToString();
                    ((ExcelServerWebSA)sa).LoadBalancingScheme = tsa.GetProperty("LoadBalancingScheme").GetValue(spsa).ToString();
                    ((ExcelServerWebSA)sa).MemoryCacheThreshold = tsa.GetProperty("MemoryCacheThreshold").GetValue(spsa).ToString();
                    ((ExcelServerWebSA)sa).PrivateBytesMax = tsa.GetProperty("PrivateBytesMax").GetValue(spsa).ToString();
                    ((ExcelServerWebSA)sa).SessionsPerUserMax = tsa.GetProperty("SessionsPerUserMax").GetValue(spsa).ToString();
                    ((ExcelServerWebSA)sa).SiteCollectionAnonymousSessionsMax = tsa.GetProperty("SiteCollectionAnonymousSessionsMax").GetValue(spsa).ToString();
                    ((ExcelServerWebSA)sa).TerminateProcessOnAccessViolation = tsa.GetProperty("TerminateProcessOnAccessViolation").GetValue(spsa).ToString();
                    ((ExcelServerWebSA)sa).ThrottleAccessViolationsPerSiteCollection = tsa.GetProperty("ThrottleAccessViolationsPerSiteCollection").GetValue(spsa).ToString();
                    ((ExcelServerWebSA)sa).UnattendedAccountApplicationId = tsa.GetProperty("UnattendedAccountApplicationId").GetValue(spsa).ToString();
                    ((ExcelServerWebSA)sa).UnusedObjectAgeMax = tsa.GetProperty("UnusedObjectAgeMax").GetValue(spsa).ToString();
                    ((ExcelServerWebSA)sa).UseEffectiveUserName = tsa.GetProperty("UseEffectiveUserName").GetValue(spsa).ToString();
                    ((ExcelServerWebSA)sa).WorkbookCache = tsa.GetProperty("WorkbookCache").GetValue(spsa).ToString();
                    ((ExcelServerWebSA)sa).WorkbookCacheSizeMax = tsa.GetProperty("WorkbookCacheSizeMax").GetValue(spsa).ToString();
                    ((ExcelServerWebSA)sa).WorkbookModelUsageTracker = tsa.GetProperty("WorkbookModelUsageTracker").GetValue(spsa).ToString();
                    break;
                case "UserProfileApplication":
                    sa = new UserProfileSA();
                    ((UserProfileSA)sa).ActiveDirectoryImportDcTimeoutInMinutes = Convert.ToInt32(tsa.GetProperty("ActiveDirectoryImportDcTimeoutInMinutes").GetValue(spsa));
                    ((UserProfileSA)sa).ActiveDirectoryImportDefragIncrement = Convert.ToInt32(tsa.GetProperty("ActiveDirectoryImportDefragIncrement").GetValue(spsa));
                    ((UserProfileSA)sa).ActiveDirectoryImportDefragThresholdInMilliseconds = Convert.ToInt32(tsa.GetProperty("ActiveDirectoryImportDefragThresholdInMilliseconds").GetValue(spsa));
                    ((UserProfileSA)sa).ActiveDirectoryImportFailedRetryCount = Convert.ToInt32(tsa.GetProperty("ActiveDirectoryImportFailedRetryCount").GetValue(spsa));
                    ((UserProfileSA)sa).ActiveDirectoryImportFailedRetryThreshold = Convert.ToInt32(tsa.GetProperty("ActiveDirectoryImportFailedRetryThreshold").GetValue(spsa));
                    ((UserProfileSA)sa).ActiveDirectoryImportOUFilterExpirationDays = Convert.ToInt32(tsa.GetProperty("ActiveDirectoryImportOUFilterExpirationDays").GetValue(spsa));
                    ((UserProfileSA)sa).ContinousSyncRunInterval = Convert.ToInt32(tsa.GetProperty("ContinousSyncRunInterval").GetValue(spsa));
                    ((UserProfileSA)sa).DaysWorthOfActivityFeedsToKeep = Convert.ToUInt32(tsa.GetProperty("DaysWorthOfActivityFeedsToKeep").GetValue(spsa));
                    ((UserProfileSA)sa).DisableAddCommentWebService = Convert.ToBoolean(tsa.GetProperty("DisableAddCommentWebService").GetValue(spsa));
                    ((UserProfileSA)sa).DisableProfileCreationWebServicesForTenants = Convert.ToBoolean(tsa.GetProperty("DisableProfileCreationWebServicesForTenants").GetValue(spsa));
                    ((UserProfileSA)sa).DocumentsFollowingLimit = Convert.ToUInt32(tsa.GetProperty("DocumentsFollowingLimit").GetValue(spsa));
                    ((UserProfileSA)sa).FeedCacheLastModifiedTimeTtlDeltaHours = Convert.ToInt32(tsa.GetProperty("FeedCacheLastModifiedTimeTtlDeltaHours").GetValue(spsa));
                    ((UserProfileSA)sa).FeedCacheObjectCountLimit = Convert.ToInt32(tsa.GetProperty("FeedCacheObjectCountLimit").GetValue(spsa));
                    ((UserProfileSA)sa).FeedCacheRemoteFarmRepopulationIntervalMinutes = Convert.ToInt32(tsa.GetProperty("FeedCacheRemoteFarmRepopulationIntervalMinutes").GetValue(spsa));
                    ((UserProfileSA)sa).FeedCacheRoomForGrowth = Convert.ToInt32(tsa.GetProperty("FeedCacheRoomForGrowth").GetValue(spsa));
                    ((UserProfileSA)sa).FeedCacheTTLHours = Convert.ToInt32(tsa.GetProperty("FeedCacheTTLHours").GetValue(spsa));
                    ((UserProfileSA)sa).FIMWebClientTimeOut = Convert.ToInt32(tsa.GetProperty("FIMWebClientTimeOut").GetValue(spsa));
                    ((UserProfileSA)sa).IsSynchronizationRunning = Convert.ToBoolean(tsa.GetProperty("IsSynchronizationRunning").GetValue(spsa));
                    ((UserProfileSA)sa).IsUsersOnlyILMImport = Convert.ToBoolean(tsa.GetProperty("IsUsersOnlyILMImport").GetValue(spsa));
                    ((UserProfileSA)sa).MaxSynchronizationRunRetryCount = Convert.ToInt32(tsa.GetProperty("MaxSynchronizationRunRetryCount").GetValue(spsa));
                    ((UserProfileSA)sa).NetBIOSDomainNamesEnabled = Convert.ToBoolean(tsa.GetProperty("NetBIOSDomainNamesEnabled").GetValue(spsa));
                    ((UserProfileSA)sa).NoILMUsed = Convert.ToBoolean(tsa.GetProperty("NoILMUsed").GetValue(spsa));
                    ((UserProfileSA)sa).PeopleFollowingLimit = Convert.ToInt32(tsa.GetProperty("PeopleFollowingLimit").GetValue(spsa));
                    ((UserProfileSA)sa).ProfileImportThreadCount = Convert.ToInt32(tsa.GetProperty("ProfileImportThreadCount").GetValue(spsa));
                    ((UserProfileSA)sa).Secret = (Guid)tsa.GetProperty("Secret").GetValue(spsa);
                    ((UserProfileSA)sa).SecTrimCacheEnabled = Convert.ToBoolean(tsa.GetProperty("SecTrimCacheEnabled").GetValue(spsa));
                    ((UserProfileSA)sa).SecTrimCacheMaxCacheTTLMinutes = Convert.ToInt32(tsa.GetProperty("SecTrimCacheMaxCacheTTLMinutes").GetValue(spsa));
                    ((UserProfileSA)sa).SecTrimCacheMaxNumberOfDataItems = Convert.ToInt32(tsa.GetProperty("SecTrimCacheMaxNumberOfDataItems").GetValue(spsa));
                    ((UserProfileSA)sa).SecTrimCacheMaxRetryCount = Convert.ToInt32(tsa.GetProperty("SecTrimCacheMaxRetryCount").GetValue(spsa));
                    ((UserProfileSA)sa).SecTrimCacheNonAuthoritativeAccessTTLMinutes = Convert.ToInt32(tsa.GetProperty("SecTrimCacheNonAuthoritativeAccessTTLMinutes").GetValue(spsa));
                    ((UserProfileSA)sa).SecTrimCacheThrottledTTLMinutes = Convert.ToInt32(tsa.GetProperty("SecTrimCacheThrottledTTLMinutes").GetValue(spsa));
                    ((UserProfileSA)sa).SecTrimMaxNumberOfSocialUrls = Convert.ToInt32(tsa.GetProperty("SecTrimMaxNumberOfSocialUrls").GetValue(spsa));
                    ((UserProfileSA)sa).SecTrimOptimizationsEnabled = Convert.ToBoolean(tsa.GetProperty("SecTrimOptimizationsEnabled").GetValue(spsa));
                    ((UserProfileSA)sa).SendWelcomeEmail = Convert.ToBoolean(tsa.GetProperty("SendWelcomeEmail").GetValue(spsa));
                    ((UserProfileSA)sa).SitesFollowingLimit = Convert.ToInt32(tsa.GetProperty("SitesFollowingLimit").GetValue(spsa));
                    ((UserProfileSA)sa).SkipBDCImport = Convert.ToBoolean(tsa.GetProperty("SkipBDCImport").GetValue(spsa));
                    break;
                case "PsiServiceApplication":
                    sa = new PsiSA();
                    ((PsiSA)sa).CurrentPCSSettings = tsa.GetProperty("CurrentPCSSettings").GetValue(spsa).ToString();
                    ((PsiSA)sa).CurrentSessionsPerUser = tsa.GetProperty("CurrentSessionsPerUser").GetValue(spsa).ToString();
                    ((PsiSA)sa).NewUsername = tsa.GetProperty("NewUsername").GetValue(spsa).ToString();
                    ((PsiSA)sa).ProvisionSettingsCollection = tsa.GetProperty("ProvisionSettingsCollection").GetValue(spsa).ToString();
                    ((PsiSA)sa).QueueSettings = tsa.GetProperty("QueueSettings").GetValue(spsa).ToString();
                    ((PsiSA)sa).ServiceAppTimerJob = tsa.GetProperty("ServiceAppTimerJob").GetValue(spsa).ToString();
                    ((PsiSA)sa).SiteCollection = tsa.GetProperty("SiteCollection").GetValue(spsa).ToString();
                    ((PsiSA)sa).SqlRolesTheIdentityMustBeIn = tsa.GetProperty("SqlRolesTheIdentityMustBeIn").GetValue(spsa).ToString();
                    ((PsiSA)sa).Username = tsa.GetProperty("Username").GetValue(spsa).ToString();
                    break;
                case "SPSubscriptionSettingsServiceApplication":
                    sa = new SPSubscriptionSettingsSA();
                    break;
                case "WordServiceApplication":
                    sa = new WordSA();
                    ((WordSA)sa).BatchWorkerTimeout = (TimeSpan)tsa.GetProperty("BatchWorkerTimeout").GetValue(spsa);
                    ((WordSA)sa).ConversionsPerInstance = Convert.ToInt32(tsa.GetProperty("ConversionsPerInstance").GetValue(spsa));
                    ((WordSA)sa).ConversionTimeout = (TimeSpan)tsa.GetProperty("ConversionTimeout").GetValue(spsa);
                    object owordsadb = tsa.GetProperty("Database").GetValue(spsa);
                    ServiceApplicationDB WordSADB = new ServiceApplicationDB();
                    WordSADB.DatabaseConnectionString = owordsadb.GetType().GetProperty("DatabaseConnectionString").GetValue(owordsadb).ToString();
                    WordSADB.DiskSizeRequired = Convert.ToInt32(owordsadb.GetType().GetProperty("DiskSizeRequired").GetValue(owordsadb));
                    WordSADB.LegacyDatabaseConnectionString = owordsadb.GetType().GetProperty("LegacyDatabaseConnectionString").GetValue(owordsadb).ToString();
                    ((WordSA)sa).Database = WordSADB;
                    ((WordSA)sa).DisableBinaryFileScan = Convert.ToBoolean(tsa.GetProperty("DisableBinaryFileScan").GetValue(spsa));
                    ((WordSA)sa).DisableEmbeddedFonts = Convert.ToBoolean(tsa.GetProperty("DisableEmbeddedFonts").GetValue(spsa));
                    ((WordSA)sa).GoldenRatio = Convert.ToInt32(tsa.GetProperty("GoldenRatio").GetValue(spsa));
                    ((WordSA)sa).JobExpirationDays = Convert.ToInt32(tsa.GetProperty("JobExpirationDays").GetValue(spsa));
                    ((WordSA)sa).KeepAliveTimeout = (TimeSpan)tsa.GetProperty("KeepAliveTimeout").GetValue(spsa);
                    ((WordSA)sa).MaximumConversionAttempts = Convert.ToInt32(tsa.GetProperty("MaximumConversionAttempts").GetValue(spsa));
                    ((WordSA)sa).MaximumConversionTime = (TimeSpan)tsa.GetProperty("MaximumConversionTime").GetValue(spsa);
                    ((WordSA)sa).MaximumMemoryUsage = Convert.ToInt32(tsa.GetProperty("MaximumMemoryUsage").GetValue(spsa));
                    ((WordSA)sa).MaximumSyncConversionRequests = Convert.ToInt32(tsa.GetProperty("MaximumSyncConversionRequests").GetValue(spsa));
                    ((WordSA)sa).RecycleProcessThreshold = Convert.ToInt32(tsa.GetProperty("RecycleProcessThreshold").GetValue(spsa));
                    ((WordSA)sa).TimerJobFrequency = (TimeSpan)tsa.GetProperty("TimerJobFrequency").GetValue(spsa);
                    ((WordSA)sa).TotalActiveProcesses = Convert.ToInt32(tsa.GetProperty("TotalActiveProcesses").GetValue(spsa));
                    ((WordSA)sa).UseFontEmbeddingSettingsForFixedFormats = Convert.ToBoolean(tsa.GetProperty("UseFontEmbeddingSettingsForFixedFormats").GetValue(spsa));
                    ((WordSA)sa).WordServiceFormats = tsa.GetProperty("WordServiceFormats").GetValue(spsa).ToString();
                    break;
                case "PowerPointConversionServiceApplication":
                    sa = new PowerPointConversionSA();
                    ((PowerPointConversionSA)sa).CacheExpirationPeriodInSeconds = Convert.ToUInt32(tsa.GetProperty("CacheExpirationPeriodInSeconds").GetValue(spsa));
                    ((PowerPointConversionSA)sa).CachePath = tsa.GetProperty("CachePath").GetValue(spsa).ToString();
                    ((PowerPointConversionSA)sa).MaximumConversionsPerWorker = Convert.ToUInt32(tsa.GetProperty("MaximumConversionsPerWorker").GetValue(spsa));
                    ((PowerPointConversionSA)sa).WorkerKeepAliveTimeoutInSeconds = Convert.ToUInt32(tsa.GetProperty("WorkerKeepAliveTimeoutInSeconds").GetValue(spsa));
                    ((PowerPointConversionSA)sa).WorkerProcessCount = Convert.ToUInt32(tsa.GetProperty("WorkerProcessCount").GetValue(spsa));
                    ((PowerPointConversionSA)sa).WorkerTimeoutInSeconds = Convert.ToUInt32(tsa.GetProperty("WorkerTimeoutInSeconds").GetValue(spsa));
                    break;
                case "SPTopologyWebServiceApplication":
                    sa = new SPTopologyWebSA();
                    ((SPTopologyWebSA)sa).IsBackwardsCompatible = tsa.GetProperty("IsBackwardsCompatible").GetValue(spsa).ToString();
                    break;
                case "TranslationServiceApplication":
                    sa = new TranslationSA();
                    ((TranslationSA)sa).BatchWorkerTimeout = (TimeSpan)tsa.GetProperty("BatchWorkerTimeout").GetValue(spsa);
                    ServiceApplicationDB TranslationSADB = new ServiceApplicationDB();
                    object oTranslationSADB = tsa.GetProperty("Database").GetValue(spsa);
                    TranslationSADB.DatabaseConnectionString = oTranslationSADB.GetType().GetProperty("DatabaseConnectionString").GetValue(oTranslationSADB).ToString();
                    TranslationSADB.DiskSizeRequired = Convert.ToInt32(oTranslationSADB.GetType().GetProperty("DiskSizeRequired").GetValue(oTranslationSADB));
                    TranslationSADB.LegacyDatabaseConnectionString = oTranslationSADB.GetType().GetProperty("LegacyDatabaseConnectionString").GetValue(oTranslationSADB).ToString();
                    ((TranslationSA)sa).Database = oTranslationSADB;
                    ((TranslationSA)sa).DisableBinaryFileScan = Convert.ToBoolean(tsa.GetProperty("DisableBinaryFileScan").GetValue(spsa));
                    ((TranslationSA)sa).InterleaveItemsByPartition = Convert.ToBoolean(tsa.GetProperty("InterleaveItemsByPartition").GetValue(spsa));
                    ((TranslationSA)sa).JobExpirationDays = Convert.ToInt32(tsa.GetProperty("JobExpirationDays").GetValue(spsa));
                    ((TranslationSA)sa).KeepAliveTimeout = (TimeSpan)tsa.GetProperty("KeepAliveTimeout").GetValue(spsa);
                    ((TranslationSA)sa).MachineTranslationAddress = tsa.GetProperty("MachineTranslationAddress").GetValue(spsa).ToString();
                    ((TranslationSA)sa).MachineTranslationCategory = tsa.GetProperty("MachineTranslationCategory").GetValue(spsa) == null ? "" : tsa.GetProperty("MachineTranslationCategory").GetValue(spsa).ToString();
                    ((TranslationSA)sa).MachineTranslationClientId = tsa.GetProperty("MachineTranslationClientId").GetValue(spsa).ToString();
                    ((TranslationSA)sa).MachineTranslationWebProxyAddress = tsa.GetProperty("MachineTranslationWebProxyAddress").GetValue(spsa) == null ? "" : tsa.GetProperty("MachineTranslationWebProxyAddress").GetValue(spsa).ToString();
                    ((TranslationSA)sa).MaximumBinaryFileSize = Convert.ToInt32(tsa.GetProperty("MaximumBinaryFileSize").GetValue(spsa));
                    ((TranslationSA)sa).MaximumConnectionIdleTime = Convert.ToInt32(tsa.GetProperty("MaximumConnectionIdleTime").GetValue(spsa));
                    ((TranslationSA)sa).MaximumItemsPerDay = Convert.ToInt32(tsa.GetProperty("MaximumItemsPerDay").GetValue(spsa));
                    ((TranslationSA)sa).MaximumItemsPerPartitionPerDay = Convert.ToInt32(tsa.GetProperty("MaximumItemsPerPartitionPerDay").GetValue(spsa));
                    ((TranslationSA)sa).MaximumSyncTranslationRequests = Convert.ToInt32(tsa.GetProperty("MaximumSyncTranslationRequests").GetValue(spsa));
                    ((TranslationSA)sa).MaximumTextFileSize = Convert.ToInt32(tsa.GetProperty("MaximumTextFileSize").GetValue(spsa));
                    ((TranslationSA)sa).MaximumTranslationAttempts = Convert.ToInt32(tsa.GetProperty("MaximumTranslationAttempts").GetValue(spsa));
                    ((TranslationSA)sa).MaximumTranslationTime = (TimeSpan)tsa.GetProperty("MaximumTranslationTime").GetValue(spsa);
                    ((TranslationSA)sa).MaximumWordCharacterCount = Convert.ToInt32(tsa.GetProperty("MaximumWordCharacterCount").GetValue(spsa));
                    ((TranslationSA)sa).RecycleProcessThreshold = Convert.ToInt32(tsa.GetProperty("RecycleProcessThreshold").GetValue(spsa));
                    ((TranslationSA)sa).TimerJobFrequency = (TimeSpan)tsa.GetProperty("TimerJobFrequency").GetValue(spsa);
                    ((TranslationSA)sa).TotalActiveProcesses = Convert.ToInt32(tsa.GetProperty("TotalActiveProcesses").GetValue(spsa));
                    ((TranslationSA)sa).TranslationsPerInstance = Convert.ToInt32(tsa.GetProperty("TranslationsPerInstance").GetValue(spsa));

                    break;
                default:
                    sa = new ServiceApplication();
                    break;

            }

            sa.ApplicationClassId = spsa.ApplicationClassId;
            sa.ApplicationVersion = spsa.ApplicationVersion;
            sa.DisplayName = spsa.DisplayName;
            sa.ManageLink = spsa.ManageLink == null ? " " : spsa.ManageLink.Url;
            sa.Name = spsa.Name;
            sa.TypeName = spsa.TypeName;
            sa.PermissionsLink = spsa.PermissionsLink == null ? " " : spsa.PermissionsLink.Url;
            sa.PropertiesLink = spsa.PropertiesLink == null ? " " : spsa.PropertiesLink.Url;

            if (spsa is SPIisWebServiceApplication)
            {
                SPIisWebServiceApplication spiwsa = spsa as SPIisWebServiceApplication;
                sa.ApplicationPoolName = spiwsa.ApplicationPool.DisplayName;
                sa.ApplicationPoolAccount = FillServiceAccount(spiwsa.ApplicationPool.ProcessAccount);
                sa.Comments = spiwsa.Comments;
                List<string> lstStr = new List<string>();
                foreach (Uri uri in spiwsa.DefaultEndpoint.ListenUris)
                    lstStr.Add(uri.AbsoluteUri);
                sa.DefaultEndpoint = lstStr.ToArray();
                sa.IisVirtualDirectoryPath = spiwsa.IisVirtualDirectoryPath;
                sa.Shared = spiwsa.Shared;
                sa.TermsOfServiceUri = spiwsa.TermsOfServiceUri == null ? null : spiwsa.TermsOfServiceUri.AbsoluteUri;
                sa.Uri = spiwsa.Uri.AbsoluteUri;

            }

            return sa;

        }
        private static string FillServiceAccount(SPProcessAccount sPProcessAccount)
        {
            string account = new System.Security.Principal.SecurityIdentifier(sPProcessAccount.SecurityIdentifier.Value).Translate(typeof(System.Security.Principal.NTAccount)).ToString();
            return account;
        }
    }

}
